package com.agileai.crm.module.customer.handler;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import com.agileai.common.KeyGenerator;
import com.agileai.crm.common.PrivilegeHelper;
import com.agileai.crm.cxmodule.CustomerGroup8ContentManage;
import com.agileai.domain.DataParam;
import com.agileai.domain.DataRow;
import com.agileai.hotweb.annotation.PageAction;
import com.agileai.hotweb.bizmoduler.core.TreeAndContentManage;
import com.agileai.hotweb.controller.core.TreeAndContentManageEditHandler;
import com.agileai.hotweb.domain.FormSelect;
import com.agileai.hotweb.domain.FormSelectFactory;
import com.agileai.hotweb.domain.core.User;
import com.agileai.hotweb.renders.AjaxRenderer;
import com.agileai.hotweb.renders.LocalRenderer;
import com.agileai.hotweb.renders.RedirectRenderer;
import com.agileai.hotweb.renders.ViewRenderer;
import com.agileai.util.DateUtil;

public class CustomerInfoEditHandler extends TreeAndContentManageEditHandler {
	protected String defaultTabId = "param";
	protected String baseTablePK = "CUST_ID";
	protected HashMap<String, String> tabIdMapping = new HashMap<String,String>();
	@SuppressWarnings("rawtypes")
	protected Class listHandlerClass = null;
	public CustomerInfoEditHandler() {
		super();
		this.serviceId = buildServiceId(CustomerGroup8ContentManage.class);
		this.tabId = "CustomerInfo";
		this.columnIdField = "GRP_ID";
		this.contentIdField = "CUST_ID";
		this.defaultTabId = "_base";
		this.listHandlerClass = CustomerGroup8ContentListHandler.class;
	}

	public ViewRenderer prepareDisplay(DataParam param) {
		User user = (User) this.getUser();
		PrivilegeHelper privilegeHelper = new PrivilegeHelper(user);
		if (!privilegeHelper.isSalesDirector()) {
			param.put("currentUserCode", user.getUserId());
			setAttribute("hasRight", false);
		} else {
			param.put("currentUserCode", "");
			setAttribute("hasRight", true);
		}
		String operaType = param.get(OperaType.KEY);
		if (isReqRecordOperaType(operaType)) {
			DataRow record = getService().getCustomerInfoRecord(param);
			this.setAttributes(record);
		}
		String currentSubTableId = param.get("currentSubTableId", defaultTabId);
		if (currentSubTableId.equals("_base") || currentSubTableId.equals("contactPerson")) {
			String subRecordsKey = "contactPersonRecords";
			if (!this.getAttributesContainer().containsKey(subRecordsKey)) {
				List<DataRow> subRecords = getService().findSubRecords(
						"contactPerson", param);
				this.setAttribute("contactPerson" + "Records", subRecords);
			}
		}
		
		tabIdMapping.put(currentSubTableId, "Layer0");
		tabIdMapping.put("visit", "Layer1");
		tabIdMapping.put("opportunity", "Layer2");
		tabIdMapping.put("order", "Layer3");
		
		if("insert".equals(operaType)){
			String pKeyValue = KeyGenerator.instance().genKey();
			param.put("CUST_ID", pKeyValue);
			setAttribute("CUST_ID", pKeyValue);
			setAttribute("doDetail", true); 
			setAttribute("doConfirm", false); 
			setAttribute("doConfirmCounter",false); 
			setAttribute("dosubmit", false);
			setAttribute("dosubmitCounter", false);
			this.setAttribute("currentSubTableId", currentSubTableId);
			this.setAttribute("currentSubTableIndex",
					getTabIndex(currentSubTableId));
			String operateType = param.get(OperaType.KEY);
			this.setOperaType(operateType);
			processPageAttributes(param);
			return new LocalRenderer(getPage());
		}

		if("update".equals(operaType)){
			setAttribute("doDetail", true);
			setAttribute("doConfirm", false); 
			setAttribute("doConfirmCounter",false); 
			setAttribute("dosubmit", true);
			setAttribute("dosubmitCounter", false);
		}
		
		if("detail".equals(operaType)){
			DataRow record = getService().getCustomerInfoRecord(param);
			if("init".equals(record.get("CUST_STATE"))){
				setAttribute("doDetail", true);
				setAttribute("dosubmit", true);
				setAttribute("doConfirm", false); 
				setAttribute("doConfirmCounter",false); 
			}else if("Submit".equals(record.get("CUST_STATE"))){
				setAttribute("doDetail", false);
				setAttribute("doConfirm", true); 
				setAttribute("doConfirmCounter",false); 
				setAttribute("dosubmit", false);
				setAttribute("dosubmitCounter", true);
			}else if("Confirm".equals(record.get("CUST_STATE"))){
				setAttribute("doDetail", false);
				setAttribute("doConfirm", false); 
				setAttribute("doConfirmCounter",true); 
				setAttribute("dosubmit", false);
				setAttribute("dosubmitCounter", false);
			}
		}
		
		if(OperaType.COPY.equals(operaType)){
			setAttribute("doDetail", true);
			setAttribute("dosubmit", true);
		}
		
		if ("confirm".equals(operaType)) {
			DataRow record = getService().getCustomerInfoRecord(param);
			setAttribute("doDetail", false);
			setAttribute("doConfirm", true); 
			setAttribute("doConfirmCounter",false); 
			setAttribute("dosubmit", false);
			setAttribute("dosubmitCounter", true);
			if (!isReqRecordOperaType(operaType)) {
				this.setAttributes(record);
				this.setAttribute("CUST_CONFIRM_NAME", user.getUserName());
				this.setAttribute("CUST_CONFIRM_ID", user.getUserId());
				if (this.getAttribute("CUST_CONFIRM_TIME") == null) {
					String date = DateUtil.getDateByType(
							DateUtil.YYMMDDHHMI_HORIZONTAL, new Date());
					this.setAttribute("CUST_CONFIRM_TIME", date);
				}
			}
		}
		
		if("confirmCounter".equals(operaType)){
			DataRow record = getService().getCustomerInfoRecord(param);
			this.setAttributes(record);
			setAttribute("doDetail", false); 
			setAttribute("doConfirm",false); 
			setAttribute("doConfirmCounter",true); 
			setAttribute("dosubmit",false);
			setAttribute("dosubmitCounter",false);
		}
		this.setAttribute("currentSubTableId", currentSubTableId);
		this.setAttribute("currentSubTableIndex",
				getTabIndex(currentSubTableId));
		String operateType = param.get(OperaType.KEY);
		this.setOperaType(operateType);
		processPageAttributes(param);
		
		DataRow record = getService().getCustomerInfoRecord(param);
		String custProvince =(String) record.get("CUST_PROVINCE");
		if(custProvince!=null){
			List<DataRow> records = getService().findCityRecords(custProvince);
			FormSelect formSelect = new FormSelect();
			formSelect.setKeyColumnName("CITY_ID");
			formSelect.setValueColumnName("CITY_NAME");
			formSelect.putValues(records);
			formSelect.setSelectedValue(record.getString("CUST_CITY"));
			this.setAttribute("CUST_CITY", formSelect);
		}
        FormSelect formSelect = this.buildSalManSelect(param);
        this.setAttribute("salMans", formSelect);
        
		setAttribute("currentLayerleId", tabIdMapping.get(currentSubTableId));
		return new LocalRenderer(getPage());
	}

	public ViewRenderer doAddEntryRecordAction(DataParam param) {
		String currentSubTableId = param.get("currentSubTableId");
		int currentRecordSize = param.getInt("currentRecordSize");
		List<DataRow> subRecords = new ArrayList<DataRow>();
		String[] entryEditFields = this.getEntryEditFields(currentSubTableId);
		for (int i = 0; i < currentRecordSize; i++) {
			DataRow row = new DataRow();
			for (int j = 0; j < entryEditFields.length; j++) {
				String field = entryEditFields[j];
				row.put(field, param.get(field + "_" + i));
			}
			row.put("_state", param.get("state_" + i));
			subRecords.add(row);
		}
		String foreignKey = this.getEntryEditForeignKey(currentSubTableId);
		subRecords.add(new DataRow("_state", "insert", foreignKey, param
				.get(baseTablePK)));
		String subRecordsKey = currentSubTableId + "Records";
		this.setAttribute(subRecordsKey, subRecords);
		return prepareDisplay(param);
	}

	public ViewRenderer doSaveAction(DataParam param) {
		String rspText = SUCCESS;
		TreeAndContentManage service = this.getService();
		String operateType = param.get(OperaType.KEY);
		User user = (User) getUser();
		PrivilegeHelper privilegeHelper = new PrivilegeHelper(user);
		if (OperaType.CREATE.equals(operateType)) {
			String colIdField = service.getTabIdAndColFieldMapping().get(
					this.tabId);
			String columnId = param.get(this.columnIdField);
			if("".equals(columnId)){
				DataRow dataRow = getService().queryTempGrpId(param);
				columnId = dataRow.getString("GRP_ID");
			}
			param.put(colIdField, columnId);
			String pKeyValue = param.get("CUST_ID");
			getService().createtContentRecord(tabId, param, pKeyValue);
			if(privilegeHelper.isSalesMan()){
				DataParam salesManParam = new DataParam("custId",pKeyValue,"userId",user.getUserId()); 
				getService().addSalesManRelation(salesManParam);
			}
		} else if (OperaType.UPDATE.equals(operateType)) {
			getService().updatetContentRecord(tabId, param);
			saveSubRecords(param);
		} else if ("confirm".equals(operateType)) {
			getService().updatetConfirmRecord(tabId, param);
			saveSubRecords(param);
		}
		return new AjaxRenderer(rspText);
	}
	
	@PageAction
	public ViewRenderer refreshCitySelect(DataParam param){
		String responseText = FAIL;
		String custProvince = param.get("CUST_PROVINCE");
		List<DataRow> records = getService().findCityRecords(custProvince);
		FormSelect formSelect = new FormSelect();
		formSelect.setKeyColumnName("CITY_ID");
		formSelect.setValueColumnName("CITY_NAME");
		formSelect.putValues(records);
		
		responseText = formSelect.getSyntax();
		
		return new AjaxRenderer(responseText);
	}
	
	public ViewRenderer doSaveMasterRecordAction(DataParam param) {
		String operateType = param.get(OperaType.KEY);
		String responseText = "fail";
		if (OperaType.CREATE.equals(operateType)) {
			responseText = param.get("CUST_ID");
		} else if (OperaType.UPDATE.equals(operateType)) {
			saveSubRecords(param);
			responseText = param.get("CUST_ID");
		} else if (OperaType.DETAIL.equals(operateType)) {
			saveSubRecords(param);
			responseText = param.get("CUST_ID");
		}
		return new AjaxRenderer(responseText);
	}

	protected void saveSubRecords(DataParam param) {
		param.buildParam("state_");
		List<DataParam> updateList = param.getUpdateParam();
		List<DataParam> insertList = param.getInsertParam();
		if (updateList.size() > 0 || insertList.size() > 0) {
			this.getService().saveSubRecords(param, insertList, updateList);
		}
	}

	public ViewRenderer doDeleteEntryRecordAction(DataParam param) {
		String currentSubTableId = param.get("currentSubTableId");
		int currentRecordIndex = param.getInt("currentRecordIndex");
		String state = param.get("state_" + currentRecordIndex);

		int currentRecordSize = param.getInt("currentRecordSize");
		List<DataRow> subRecords = new ArrayList<DataRow>();
		String[] entryEditFields = this.getEntryEditFields(currentSubTableId);
		for (int i = 0; i < currentRecordSize; i++) {
			if (i == currentRecordIndex)
				continue;
			DataRow row = new DataRow();
			for (int j = 0; j < entryEditFields.length; j++) {
				String field = entryEditFields[j];
				row.put(field, param.get(field + "_" + i));
			}
			row.put("_state", param.get("state_" + i));
			subRecords.add(row);
		}
		String subRecordsKey = currentSubTableId + "Records";
		this.setAttribute(subRecordsKey, subRecords);

		if (!state.equals("insert")) {
			DataParam deleteParam = new DataParam();
			String pKField = getEntryEditTablePK(currentSubTableId);
			deleteParam.put(pKField,
					param.get(pKField + "_" + currentRecordIndex));
			getService().deleteSubRecord(currentSubTableId, deleteParam);
		}
		return prepareDisplay(param);
	}

	public ViewRenderer doChangeSubTableAction(DataParam param) {
		return prepareDisplay(param);
	}


	protected void processPageAttributes(DataParam param) {
		setAttribute("CUST_INDUSTRY", FormSelectFactory.create("CUST_INDUSTRY")
				.addSelectedValue(getOperaAttributeValue("CUST_INDUSTRY", "")));
		setAttribute("CUST_SCALE", FormSelectFactory.create("CUST_SCALE")
				.addSelectedValue(getOperaAttributeValue("CUST_SCALE", "")));
		setAttribute("CUST_NATURE", FormSelectFactory.create("CUST_NATURE")
				.addSelectedValue(getOperaAttributeValue("CUST_NATURE", "")));
		setAttribute("CUST_STATE", FormSelectFactory.create("CUST_STATE")
				.addSelectedValue(getOperaAttributeValue("CUST_STATE", "init")));
		setAttribute("CUST_LEVEL", FormSelectFactory.create("CUST_LEVEL")
				.addSelectedValue(getOperaAttributeValue("CUST_LEVEL", "")));
		setAttribute("CUST_PROGRESS_STATE", FormSelectFactory.create("CUST_PROGRESS_STATE")
				.addSelectedValue(getOperaAttributeValue("CUST_PROGRESS_STATE", "")));
		initMappingItem("CONT_SEX", FormSelectFactory.create("USER_SEX")
				.getContent());
		setAttribute("CONT_SEXSelect", FormSelectFactory.create("USER_SEX"));

		setAttribute("GRP_ID", param.get("GRP_ID"));
		
		User user = (User) this.getUser();
		this.setAttribute("CUST_CREATE_NAME",
				this.getAttribute("CUST_CREATE_NAME", user.getUserName()));
		this.setAttribute("CUST_CREATE_ID",
				this.getAttribute("CUST_CREATE_ID", user.getUserId()));

		String date = DateUtil.getDateByType(DateUtil.YYMMDDHHMISS_HORIZONTAL,
				new Date());
		if (this.getAttribute("CUST_CREATE_TIME") == null) {
			this.setAttribute("CUST_CREATE_TIME", date);
		}
    	this.setAttribute("currentSubTableId", param.get("currentSubTableId"));
    	setAttribute("currentSubTableId",getAttributeValue("currentSubTableId", "0"));
	}

	protected String[] getEntryEditFields(String currentSubTableId) {
		List<String> temp = new ArrayList<String>();

		if ("contactPerson".equals(currentSubTableId)) {
			temp.add("CONT_ID");
			temp.add("CUST_ID");
			temp.add("CONT_JOB");
			temp.add("CONT_NAME");
			temp.add("CONT_SEX");
			temp.add("CONT_PHONE");
			temp.add("CONT_EMAIL");
			temp.add("CONT_OTHER");
		}

		return temp.toArray(new String[] {});
	}

	protected String getEntryEditTablePK(String currentSubTableId) {
		HashMap<String, String> primaryKeys = new HashMap<String, String>();
		primaryKeys.put("contactPerson", "CONT_ID");

		return primaryKeys.get(currentSubTableId);
	}
	
	protected String getTabIndex(String currentSubTableId) {
		String result = "0";
		String[] subTableIds = getService().getTableIds();
		for (int i = 0; i < subTableIds.length; i++) {
			String subId = subTableIds[i].toString();
			if (currentSubTableId.equals(subId)) {
				result = String.valueOf(i);
				break;
			}
		}
		return result;
	}

	protected String getEntryEditForeignKey(String currentSubTableId) {
		HashMap<String, String> foreignKeys = new HashMap<String, String>();
		foreignKeys.put("contactPerson", "CUST_ID");

		return foreignKeys.get(currentSubTableId);
	}

	@PageAction
	public ViewRenderer submit(DataParam param) {
		String responseText = SUCCESS;
		param.put("CUST_STATE", "Submit");
		User user = (User) this.getUser();
		param.put("CUST_SUBMIT_NAME",
				this.getAttribute("CUST_SUBMIT_NAME", user.getUserName()));
		param.put("CUST_SUBMIT_ID",
				this.getAttribute("CUST_SUBMIT_ID", user.getUserId()));
		if (this.getAttribute("CUST_SUBMIT_TIME") == null) {
			String date = DateUtil.getDateByType(
					DateUtil.YYMMDDHHMI_HORIZONTAL, new Date());
			param.put("CUST_SUBMIT_TIME", date);
		}
		getService().updateSubmitStateInfoRecord(param);
		return new AjaxRenderer(responseText);
	}
	
	@PageAction
	public ViewRenderer submitCounter(DataParam param) {
		String responseText = SUCCESS;
		param.put("CUST_STATE", "init");
		getService().updateSubmitStateInfoRecord(param);
		return new AjaxRenderer(responseText);
	}

	@PageAction
	public ViewRenderer confirm(DataParam param) {
		String responseText = SUCCESS;
		param.put("CUST_STATE", "Confirm");
		User user = (User) this.getUser();
		param.put("CUST_CONFIRM_NAME",
				this.getAttribute("CUST_CONFIRM_NAME", user.getUserName()));
		param.put("CUST_CONFIRM_ID",
				this.getAttribute("CUST_CONFIRM_ID", user.getUserId()));
		if (this.getAttribute("CUST_CONFIRM_TIME") == null) {
			String date = DateUtil.getDateByType(
					DateUtil.YYMMDDHHMI_HORIZONTAL, new Date());
			param.put("CUST_CONFIRM_TIME", date);
		}
		getService().updateConfirmStateInfoRecord(param);
		return new AjaxRenderer(responseText);
	}
	
	@PageAction
	public ViewRenderer confirmCounter(DataParam param) {
		String responseText = SUCCESS;
		param.put("CUST_STATE", "init");
		getService().updateConfirmStateInfoRecord(param);
		return new AjaxRenderer(responseText);
	}
	
	@PageAction
    public ViewRenderer addUserTreeRelation(DataParam param){
		String responseText = null;
    	String custId = param.get("CUST_ID");
    	String userIds = param.get("userIds");
    	getService().addUserTreeRelation(custId, userIds.split(","));
    	responseText = this.buildSalManSelect(param).getSyntax();
    	return new AjaxRenderer(responseText);
    }
	
    @PageAction
    public ViewRenderer delUserTreeRelation(DataParam param){
    	String responseText = null;
    	String custId = param.get("CUST_ID");
    	String userId = param.get("salMans");
    	getService().delUserTreeRelation(custId, userId);
    	responseText = this.buildSalManSelect(param).getSyntax();
    	return new AjaxRenderer(responseText);
    }
    
    private FormSelect buildSalManSelect(DataParam param){
    	param.put("custId", param.get("CUST_ID"));
    	List<DataRow> records = getService().findRecords(param);
        FormSelect formSelect = new FormSelect();
        formSelect.setKeyColumnName("USER_ID");
        formSelect.setValueColumnName("USER_NAME");
        formSelect.putValues(records);
        formSelect.addHasBlankValue(false);
        return formSelect;
    }
    
	public ViewRenderer doBackAction(DataParam param){
		return new RedirectRenderer(getHandlerURL(MyCustomerInfoManageListHandler.class));
	}
    
	protected CustomerGroup8ContentManage getService() {
		return (CustomerGroup8ContentManage) this.lookupService(this
				.getServiceId());
	}
}

